/* 字符串处理工具函数
 * 
 * author：hadeswang
 * date：2013-08-13
 */
 
#ifndef C2CPLATFORM_LIBRARY_STRING_STRING_HELPER_H
#define C2CPLATFORM_LIBRARY_STRING_STRING_HELPER_H

#include <string>
#include <vector>
#include <stdint.h>
#include <set>

namespace c2cplatform
{
namespace library
{
namespace string 
{
/**
* @fn 利用分隔符切割字符串到vector中
* 
* @param sContent [in]要被字符串
* @param sDivider [in]分割字符
* @param vecStr   [out]分割好的vector
*
* @return uint32_t 切割出的子串数量=vecStr.size()
*
*/
static inline uint32_t SplitStringIntoVector(const char * sContent, const char * sDivider, std::vector<std::string> &vecStr){
	char * sNewContent = new char [strlen(sContent)+1];
	snprintf(sNewContent,strlen(sContent)+1,"%s",sContent);

	char * pStart = sNewContent;
	char * pEnd   = sNewContent;

	std::string strContent;

	pEnd = strstr(sNewContent,sDivider);
	if(pEnd == NULL && strlen(sNewContent)>0){
		strContent = pStart; //get the last one;
		vecStr.push_back(strContent);
	}
	
	while(pEnd){
		*pEnd = '\0';
		strContent = pStart;
		vecStr.push_back(strContent);
		
		pStart = pEnd+strlen(sDivider);
		if((*pStart) == '\0'){
			break;
		}
		
		pEnd = strstr(pStart,sDivider);
		
		if(pEnd == NULL){
			strContent = pStart; //get the last one;
			vecStr.push_back(strContent);
		}
		
	}

	delete [] sNewContent;

	return vecStr.size();
}

/**
* @fn 利用分隔符切割字符串到set中，set进行了去重
* 
* @param sContent [in]要被字符串
* @param sDivider [in]分割字符
* @param vecStr   [out]分割好的vector
*
* @return uint32_t 切割出的子串数量=setStr.size()
*
*/
static inline uint32_t SplitStringIntoSet(const char * sContent, const char * sDivider, std::set<std::string> &setStr){
	char * sNewContent = new char [strlen(sContent)+1];
	snprintf(sNewContent,strlen(sContent)+1,"%s",sContent);

	char * pStart = sNewContent;
	char * pEnd   = sNewContent;

	std::string strContent;

	pEnd = strstr(sNewContent,sDivider);
	if(pEnd == NULL && strlen(sNewContent)>0){
		strContent = pStart; //get the last one;
		setStr.insert(strContent);
	}
	
	while(pEnd){
		*pEnd = '\0';
		strContent = pStart;
		setStr.insert(strContent);
		
		pStart = pEnd+strlen(sDivider);
		if((*pStart) == '\0'){
			break;
		}
		
		pEnd = strstr(pStart,sDivider);
		
		if(pEnd == NULL){
			strContent = pStart; //get the last one;
			setStr.insert(strContent);
		}
		
	}

	delete [] sNewContent;

	return setStr.size();
}

/**
* @fn 根据UTF8字符的首字节，计算该字符应有的字节长度
* 
* @param cFirstCh [in]字符的首字节
*
* @return uint32_t 该字符应有的字节长度
*
*/
static inline uint32_t GetUtf8ByteNumByFirstWord(unsigned char cFirstCh)
{
    unsigned char temp = 0x80;
    int num = 0;

    if(cFirstCh < 0x80)//ascii code.(0-127)
    {
        return 1;
    }
    while(temp & cFirstCh)
    {
        num++;
        temp = (temp >> 1);
    }

    return num;
}

/**
* @fn 计算UTF8字符串的字符数
* 
* @param strUTF8String [in]UTF8字符串
*
* @return uint32_t UTF8字符串的字符数
*
*/
static inline uint32_t GetUTF8LogicStrLen(const std::string & strUTF8String)
{
    uint32_t i,num,len = 0;
    for(i = 0;i<strUTF8String.size();)
    {
        num = GetUtf8ByteNumByFirstWord((unsigned char)strUTF8String[i]);
        len++;
        i += num;
    }
    return len;
}

/**
* @fn 用一个子串替换字符串中全部匹配的子串
* 
* @param strString [in/out]要替换的字符串
* @param strPattern [in]被替换的模式子串
* @param strNewPattern [in]要替换成的模式子串
*
*/
static inline void ReplaceAll(std::string& strString,const std::string strPattern,const std::string strNewPattern)
{
    const size_t nsize = strNewPattern.size();
    const size_t psize = strPattern.size();

    for(size_t pos = strString.find(strPattern, 0);
        pos != std::string::npos;
        pos = strString.find(strPattern, pos + nsize))
    {
        strString.replace(pos, psize, strNewPattern);
    }
}

/**
* @fn 将UTF8串中的HTML敏感字符替换为全角字符，用于HTML页面展示的文本串过滤
* 
* @param strIn [in]要替换的UTF8字符串
*
* @return std::string 替换后的UTF8字符串
*
*/
static inline std::string ReplaceDangerousCharUTF8(const std::string & strIn)
{
    std::string strOut = strIn;

    ReplaceAll(strOut, "<", "＜");
    ReplaceAll(strOut, ">", "＞");
    ReplaceAll(strOut, "\"", "＂");
    ReplaceAll(strOut, "'", "‘");
    ReplaceAll(strOut, "\\", "＼");
    ReplaceAll(strOut, "&", "＆");

    return strOut;
}

/**
* @fn 剔除字符串两端的空格(或其他字符)
* 
* @param strIn [in]要剔除两端空格的UTF8字符串
*
* @return std::string 剔除两端空格的UTF8字符串
*
*/
inline std::string Trim(const std::string& strIn,const char cCharacter=' ')
{
	if (strIn.empty())
	{
		return strIn;
	}

	size_t szBegin = strIn.find_first_not_of(cCharacter);
	size_t szEnd = strIn.find_last_not_of(cCharacter);
	if (szBegin == std::string::npos && szEnd == std::string::npos)
	{
		return "";
	}
	else if (szBegin > szEnd)
	{
		return "";
	}

	std::string strOut = strIn.substr(szBegin, szEnd - szBegin + 1);

	return strOut;
}

}
}
}

#endif
